package org.ihelpuoo.weboo.security.action;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;
import org.ihelpuoo.lang.ExceptionUtils;
import org.ihelpuoo.weboo.action.http.Action;
import org.ihelpuoo.weboo.module.ActionContext;
import org.ihelpuoo.weboo.security.Security;
import org.ihelpuoo.weboo.security.Session;

public class GetBinaryVerifyCodeAction implements Action
{

	private File							home	= null;
	private String							type	= "jpg";
	private int								w		= 20;
	private int								h		= 20;
	private int								size	= 4;
	private Map<Character, BufferedImage>	map;

	private void writeVerifyCodeToStream(char[] codes, OutputStream ops) throws IOException
	{
		BufferedImage oImg = new BufferedImage(w * codes.length,h,BufferedImage.TYPE_INT_RGB);
		Graphics2D gc = oImg.createGraphics();
		for (int i = 0; i < codes.length; i++)
		{
			BufferedImage img = map.get(codes[i]);
			gc.drawImage(img,w * i,0,null);
		}
		ImageIO.write(oImg,type,ops);
	}

	private void init(ActionContext context) throws Exception
	{
		if (null == home)
			synchronized (this)
			{
				if (null == home)
				{
					home = new File(context.getSession().getServletContext().getRealPath(
							context.properties().getString("icon-home")));
					map = new HashMap<Character, BufferedImage>();
					try
					{
						size = context.properties().getInt("size");
					}
					catch (RuntimeException e)
					{
						size = 4;
					}
					if (!home.exists())
						throw new Exception("Directory didn't exist: " + home.getAbsolutePath());
					BufferedImage img = null;
					for (int i = 0; i < Security.CODES.length; i++)
					{
						img = ImageIO.read(new File(home.getAbsolutePath() + "/"
								+ Security.CODES[i] + "." + type));
						map.put(Security.CODES[i],img);
					}
					w = img.getWidth();
					h = img.getHeight();
				}
			}
	}

	private static Logger	log	= Logger.getLogger(GetBinaryVerifyCodeAction.class);

	public void execute(ActionContext context)
	{
		try
		{
			init(context);
			Session session = context.getSession();
			char[] codes = session.refreshVerifyCode(size);
			writeVerifyCodeToStream(codes,context.getResponse().getOutputStream());
		}
		catch (IOException e)
		{
			log.warn(e.getMessage());
		}
		catch (Exception e)
		{
			log.error(ExceptionUtils.dump(e));
		}
	}

}
